import functools


# 装饰器 decorator
# 本质上，decorator就是一个返回函数的高阶函数


def log(text):
    def decorator(func):
        @functools.wraps(func)  # wrapper.__name__ = func.__name__ 不加上的话, 被装饰的函数的__name__就变成了wrapper了
        def wrapper(*args, **kw):
            print('%s %s: ' % (text, func.__name__))
            return func(*args, **kw)

        return wrapper

    return decorator


@log('execute')
def now():
    print('2017-09-05')


# 先执行log('execute')，返回的是decorator函数，再调用返回的函数，参数是now函数，返回值最终是wrapper函数
# now = log('execute')(now)

# now()

# 把@log放到now()函数的定义处，相当于执行了语句
# now = log(now)


def log4py(text='run'):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print('begin %s %s ' % (text, func.__name__))
            func(*args, **kw)
            print('end %s %s ' % (text, func.__name__))
            return func

        return wrapper

    return decorator


@log4py('mmp')
def say_hello():
    print('hello')


say_hello()
